package com.lagou.edu.factory;

import com.lagou.edu.anno.Autowired;
import com.lagou.edu.anno.Componment;
import com.lagou.edu.utils.TransactionManager;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理工厂对象
 * @author shengtsource
 */
@Componment
public class ProxyFactory {
//    private static volatile ProxyFactory proxyFactory = null;
//    private ProxyFactory() {
//
//    }
//    public static ProxyFactory getInstance() {
//        if(null == proxyFactory) {
//            synchronized (ProxyFactory.class) {
//                if(null == proxyFactory) {
//                    proxyFactory = new ProxyFactory();
//                }
//            }
//        }
//        return proxyFactory;
//    }
    @Autowired
    private TransactionManager transactionManager;
    /**
     * 获取JDK动态代理对象，增强横切逻辑
     * @param obj
     * @return
     */
    public Object getJdkProxyObject(Object obj) {
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                try{
                    //开启事务
                    transactionManager.beginTransaction();
                    result = method.invoke(obj,args);
                    transactionManager.commit();
                }catch (Exception e) {
                    transactionManager.rollback();
                    throw e;
                }
                return result;
            }
        });
    }

    /**
     * 获取Cglib动态代理对象，增强横切逻辑
     * @param obj
     * @return
     */
    public Object getCglibObject(Object obj) {
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(obj.getClass());
        //设置回调逻辑
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object result = null;
                TransactionManager transactionManager = new TransactionManager();
                try{
                    //开启事务
                    transactionManager.beginTransaction();
                    result = method.invoke(obj,args);
                    transactionManager.commit();
                }catch (Exception e) {
                    transactionManager.rollback();
                    throw e;
                }
                return result;
            }
        });
        return enhancer.create();
    }

}
